home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 June / MacFormat 25.iso / Shareware City / Developers / appe Windows 1.51.1 / event filter.c < prev    next >
Encoding:
Text File  |  1995-01-11  |  7.5 KB  |  268 lines  |  [TEXT/KAHL]

  1. // File "event filter.c" -
  2. // This source file is Copyright Matt Slot & Slot-Machines Ltd., © 1994
  3.  
  4. #include <GestaltEqu.h>
  5. #include "TextServices.h"
  6.  
  7. #include "main.h"
  8. #include "contexts.h"
  9. #include "event filter.h"
  10. #include "windows.h"
  11.  
  12. // * ****************************************************************************** *
  13. // Global Vars
  14.  
  15. extern GlobalsRec glob;
  16.     
  17. // * ****************************************************************************** *
  18. // * ****************************************************************************** *
  19.  
  20. void InsertMyFilter() {
  21.     Ptr filterPtr, endFilterPtr, helpFilterPtr;
  22.  
  23.     // Load up the Filter Handler
  24.     asm {
  25.         lea            MyJGNEFilter, a0
  26.         move.l        2(a0), filterPtr
  27.         lea            EndJGNEFilter, a0
  28.         move.l        2(a0), endFilterPtr
  29.         lea            HelperJGNEFilter, a0
  30.         move.l        2(a0), helpFilterPtr
  31.         }
  32.     glob.myContext = SaveContext(-1);
  33.  
  34.     // Duplicate function in safe spot - System Heap
  35.     glob.myFilter = NewPtrSys(StripAddress(endFilterPtr) - StripAddress(filterPtr));
  36.     BlockMove(filterPtr, glob.myFilter, GetPtrSize(glob.myFilter));
  37.     
  38.     // Get Appropriate Info and stuff into Header of JGNEFilter
  39.     BlockMove((Ptr) 0x29a, glob.myFilter+2, 4);            // Next Filter
  40.     BlockMove(&glob.myContext, glob.myFilter+6, 4);        // Context Info
  41.     BlockMove(&helpFilterPtr, glob.myFilter+10, 4);        // Address of Local Handler
  42.     
  43.     BlockMove(&glob.myFilter, (Ptr) 0x29a, 4);            // Save into Lo-Mem Global
  44.     }
  45.  
  46. // * ****************************************************************************** *
  47. // * ****************************************************************************** *
  48.  
  49. void RemoveMyFilter() {
  50.     Ptr loadPtr;
  51.     
  52.     // Actually, just disable the filter by stuffing 0 into the Event Handler storage
  53.  
  54.     DisposeContext(glob.myContext);
  55.  
  56.     loadPtr = glob.myFilter;
  57.     asm {
  58.         move.l    loadPtr, a0
  59.         move.l    #0, 10(a0)
  60.         }
  61.     }
  62.  
  63. // * ****************************************************************************** *
  64. // * ****************************************************************************** *
  65.  
  66. void DisableMyFilter(short enable) {
  67.     Ptr loadPtr, helpFilterPtr;
  68.  
  69.     loadPtr = glob.myFilter;
  70.  
  71.     if (enable) {
  72.         asm {
  73.             lea            HelperJGNEFilter, a0
  74.             move.l        2(a0), helpFilterPtr
  75.             move.l        loadPtr, a0
  76.             move.l        helpFilterPtr, 10(a0)
  77.             }
  78.         }
  79.       else {
  80.         asm {
  81.             move.l        loadPtr, a0
  82.             move.l        #0, 10(a0)
  83.             }
  84.         }
  85.     }
  86.  
  87. // * ****************************************************************************** *
  88. // * ****************************************************************************** *
  89.  
  90. void MyJGNEFilter() {
  91.     asm {
  92.         bra.s    @Continue
  93.         
  94. @Next_Filter
  95.         dc.l    0    ; Saved Address of Next jGNEFilter
  96.         
  97. @Saved_Context
  98.         dc.l    0    ; Saved Context Info for our App
  99.  
  100. @Event_Helper
  101.         dc.l    0    ; The function in my app to call
  102.         
  103. @Continue
  104.         movem.l    d0-d2/a0-a5, -(a7)
  105.         move.l    @Event_Helper, a0
  106.         move.l    a0, d0
  107.         tst.l    d0
  108.         beq        @End_Filter
  109.         
  110.         move.l    @Saved_Context, a0
  111.         move.l    a0, -(a7)
  112.         move.l    a1, -(a7)
  113.         move.l    @Event_Helper, a0
  114.         jsr        (a0)
  115.         add.l    #8, a7
  116.         
  117. @End_Filter
  118.         movem.l    (a7)+, d0-d2/a0-a5
  119.         move.l    @Next_Filter, a0
  120.         jmp        (a0)
  121.         }
  122.     }
  123. void EndJGNEFilter() { } 
  124.  
  125. // * ****************************************************************************** *
  126. // * ****************************************************************************** *
  127.  
  128. void HelperJGNEFilter(EventRecord *theEvent, ContextPtr myContext) {
  129.     short thePart, cloneFile;
  130.     Rect dragBounds;
  131.     ContextPtr frontContext;
  132.     WindowPtr theWindow, frontWindow;
  133.  
  134.     frontContext = SaveContext(0);
  135.     RestoreContext(myContext);            // DONT USE GLOBAL CONTEXT YET - A5 isnt set up
  136.     glob.frontContext = frontContext;    // Put the Apps context info into the Globals
  137.     UseResFile(cloneFile = FSpOpenResFile(&glob.cloneSpec, fsRdPerm));
  138.  
  139.     glob.theEvent = *theEvent;
  140.         
  141.     // We need to manually look for an update event -- otherwise it wont happen
  142.     if (!EmptyRgn(((WindowPeek) glob.window)->updateRgn)) DoUpdateWindow();
  143.  
  144.     switch(theEvent->what) {
  145.         case nullEvent:
  146.             DoCheckVisibility();
  147.             break;
  148.             
  149.         case mouseDown:
  150.             // The following line shouldnt be necessary... but PopupFuncs
  151.             //   doesnt like the FindServiceWindow() call... so we try to avoid it.
  152.             //   Just eliminate a few checks in some cases that we know are wrong.
  153.             if (!PtInRgn(theEvent->where, ((WindowPeek) glob.window)->strucRgn)) break;
  154.         
  155.             thePart = FindServiceWindow(theEvent->where, &theWindow);
  156.             if (theWindow != glob.window) break;
  157.             GetFrontServiceWindow(&frontWindow);
  158.                         
  159.             switch(thePart) {
  160.                 case inContent:
  161.                     if (theWindow != frontWindow) {
  162.                         SelectWindow(theWindow);
  163.                         DoUpdateWindow();
  164.                         }
  165.                     DoClickWindow();
  166.                     theEvent->what = nullEvent;
  167.                     break;
  168.                 case inDrag:
  169.                     // Generic Dragger Handling
  170.                     if (theWindow != frontWindow) {
  171.                         SelectWindow(theWindow);
  172.                         DoUpdateWindow();
  173.                         }
  174.                     dragBounds = (*GetGrayRgn())->rgnBBox;
  175.                     DragWindow(theWindow, theEvent->where, &dragBounds);
  176.                     theEvent->what = nullEvent;
  177.                     break;
  178.                 case inGrow:
  179.                     // I dont think anyone will grow a floater, so just ...
  180.                     DoClickWindow();
  181.                     theEvent->what = nullEvent;
  182.                     break;
  183.                 case inGoAway:
  184.                     // Exit gracefully - Finish this Event first
  185.                     if (TrackGoAway(theWindow, theEvent->where)) glob.quitting = 1;
  186.                     theEvent->what = nullEvent;
  187.                     break;
  188.                 case inZoomIn:
  189.                 case inZoomOut:
  190.                     if (TrackBox(theWindow, theEvent->where, thePart))
  191.                         DoZoomWindow(thePart);
  192.                     theEvent->what = nullEvent;
  193.                     break;
  194.                 default:
  195.                     break;
  196.                 }
  197.             break;
  198.             
  199.         case autoKey:
  200.         case keyDown:
  201.             if (DoKeydownWindow()) theEvent->what = nullEvent;
  202.             break;
  203.             
  204.         default:
  205.             break;
  206.         }
  207.  
  208.     CloseResFile(cloneFile);
  209.     RestoreContext(frontContext);
  210.     DisposeContext(frontContext);
  211.     }
  212.  
  213. // * ****************************************************************************** *
  214. // * ****************************************************************************** *
  215.  
  216. // If you have set the Hot Application, then this function checks whether that
  217. //   process is the front one and hides or shows the window as appropriate.
  218. void DoCheckVisibility() {
  219.     ProcessSerialNumber psn;
  220.     ProcessInfoRec pInfo;
  221.     
  222.     pInfo.processInfoLength = sizeof(pInfo);
  223.     pInfo.processName = 0;
  224.     pInfo.processAppSpec = 0;
  225.     
  226.     if (!GetFrontProcess(&psn) && !GetProcessInformation(&psn, &pInfo)) {
  227.         if (!glob.hidden && (!InScreenSaver()) &&
  228.                 ((glob.hotApplication == kAllApplications) ||
  229.                 (pInfo.processSignature == glob.hotApplication))) {
  230.             if (! ((WindowPeek) glob.window)->visible) {
  231.                 ShowHide(glob.window, -1);
  232.                 DoRevealWindow(-1);
  233.                 }
  234.             }
  235.           else if (((WindowPeek) glob.window)->visible) {
  236.             ShowHide(glob.window, 0);
  237.             DoRevealWindow(0);
  238.             }
  239.         }
  240.     }
  241.  
  242. // * ****************************************************************************** *
  243. // * ****************************************************************************** *
  244.  
  245. // Thanks to Dair Grant (dair.grant@ucl.ac.uk) - I now check the MBarHeight
  246. //   of the *Front* process, and remember (via globals) when executing in bkgd.
  247.  
  248. short InScreenSaver() {
  249.     short err, inFront;
  250.     long result;
  251.     ProcessSerialNumber frontPSN, curPSN;
  252.  
  253.     // Most screensavers should register themselves this way
  254.     if (!Gestalt('SAVR', &result) && (result & 0x02)) return(-1);
  255.  
  256.     // We also want to hide ourselves if the foreground application
  257.     // has hidden the menu bar, since this implies they're taking
  258.     // over the whole screen (and they probably don't want us visible).
  259.     
  260.     // If we are executing in the foreground app, then cache the 
  261.     // height of the menu bar for when we swap to the background.
  262.     if (!GetFrontProcess(&frontPSN) && !GetCurrentProcess(&curPSN))
  263.         if (SameProcess(&frontPSN, &curPSN, (Boolean *) &inFront)) inFront = 0;
  264.     if (inFront) glob.frontMBarHeight = GetMBarHeight();
  265.  
  266.     return(! glob.frontMBarHeight);
  267.     }
  268.